/***************************************************************************
 *   Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN  *
 *   {prenom.nom}_at_lip6.fr                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
/** @file
 * @brief Common tools used by learning algorithms
 *
 * @author Maroua HAMMAMI and Malak HAMZEH
 *
 * This file provides common tools used by various learning algorithms.
 * */
#ifndef GUM_IBOX_TOOLS_H
#define GUM_IBOX_TOOLS_H

#include <agrum/learning/InstantiationBox.h>
#include <agrum/core/inline.h>
#include <vector>
#include <agrum/core/list.h>
//#include <agrum/learning/InstantiationBox.h>

namespace gum {
using namespace std;
class InstantiationBoxChild : public InstantiationBox {
private: 
		std::vector<unsigned int> __count;
	
public: 
	// ==============================================================================
        /// basic constructor
       // ==============================================================================

	InstantiationBoxChild (unsigned int nbrModalities);

       // ==============================================================================
       /// copy constructor
      // ==============================================================================

private:  InstantiationBoxChild(const InstantiationBoxChild& Child):InstantiationBox(),__count(Child.__count)
	{
		GUM_CONS_CPY(InstantiationBoxChild);
	}


      // ==============================================================================
      /// destructor
     // ==============================================================================
public:	virtual ~InstantiationBoxChild ();

     // ==============================================================================
     /// copy operator
    // ==============================================================================

private :    InstantiationBoxChild& operator=( const InstantiationBoxChild& Child)
    {
	if(this!=&Child)
		__count=Child.count();       
	return *this;
    }
	
     // ==============================================================================
     /// gets the vector of unsigned int : __count
    // ==============================================================================

public:   	const std::vector<unsigned int>& count() const; 

     // ==============================================================================
     /// resets the vector of unsigned int to zeros
    // ==============================================================================

	void resetCount();
		
     // ==============================================================================
     /// increments the element i of the vector
    // ==============================================================================

	 void increment(int i);
 
	 }; // InstantiationBoxChild



class InstantiationBoxParent : public InstantiationBox{

public:
		typedef ListBase<unsigned int> ListCases;
private: 
		 std::vector<ListCases>*__dbCases;// un tableau nomme "dbCases" pointe sur un vecteur de type list.
		 std::vector<InstantiationBox*>__children;

public: 
	     /*Default constructor*/
	        InstantiationBoxParent(unsigned int nbrModalities);
		virtual ~InstantiationBoxParent();

	/*Copy constructor*/
InstantiationBoxParent( const InstantiationBoxParent& parent):InstantiationBox(),__children(parent.__children) {
	if(parent.__dbCases!=0)
	 __dbCases=new std::vector<ListCases>(*parent.__dbCases);
	else
		__dbCases=0;
	GUM_CONS_CPY(InstantiationBoxParent);
	}
/*copy operator*/
InstantiationBoxParent& operator=( const InstantiationBoxParent & parent) {
	if(this != &parent)
	{	GUM_OP_CPY( InstantiationBoxParent );
		if(parent.__dbCases!=0)
			 __dbCases=new std::vector<ListCases>(*parent.__dbCases);
		else
			__dbCases=0;	
		__children=parent.__children;		
	}
	return *this;
  }

		const ListCases& dbCases(unsigned int currentval) const;
		bool hasChild(unsigned int i) const;	
		void addChild(unsigned int i, InstantiationBox& __child);
		InstantiationBox* child(unsigned int i) const;
		void eraseDBCases();
		void addCases(unsigned int i, unsigned int db_cases);
		vector<unsigned int>& getAllDbCases();
		void resizeParent(unsigned int sz);
};

}//End of namespace gum
/// include the inlined functions if necessary
#ifndef GUM_NO_INLINE
#include <agrum/learning/InstantiationBoxTools.inl>
#endif /* GUM_NO_INLINE */

#endif /* GUM_IBOX_TOOLS_H */
